package org.springblade.modules.repair.service.approve;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.config.ProjectApiConfiguration;
import org.springblade.common.constant.MaintenanceSmsConstant;
import org.springblade.common.constant.TemplateMsgConstant;
import org.springblade.common.constant.VoiceConstant;
import org.springblade.common.utils.AsyncHttpUtil;
import org.springblade.common.utils.RobotUtil;
import org.springblade.common.utils.mq.AlarmSend;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.*;
import org.springblade.modules.notice.core.Process;
import org.springblade.modules.notice.core.event.NoticeEvent;
import org.springblade.modules.notice.dto.NoticeTaskParam;
import org.springblade.modules.notice.enums.BusinessType;
import org.springblade.modules.notice.enums.TriggerNodeEnum;
import org.springblade.modules.repair.dto.RobotContentDTO;
import org.springblade.modules.repair.entity.*;
import org.springblade.modules.repair.enums.*;
import org.springblade.modules.repair.service.*;
import org.springblade.modules.repair.service.approve.strategy.ApproveBusinessFlow;
import org.springblade.modules.repair.utils.DateUtils;
import org.springblade.modules.repair.vo.BusinessApproveVO;
import org.springblade.modules.repair.vo.ElevatorSimpleInfoVO;
import org.springblade.modules.repair.vo.RepairWorkVO;
import org.springblade.modules.resource.utils.SmsUtil;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.ApproveUserVO;
import org.springblade.modules.system.vo.SimpleUserVO;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.request.RequestContextHolder;

import java.time.Duration;
import java.util.*;


/**
 * @Description 报障审批流程
 * @Author ysq
 * @Date 2021/12/7
 **/
@Slf4j
public class MalfunctionFlow implements ApproveBusinessFlow {

	private final IMaintainPlanContentUserService maintainPlanContentUserService = SpringUtil.getBean(IMaintainPlanContentUserService.class);
	private final IMaintainMalfunctionWorkService maintainMalfunctionWorkService = SpringUtil.getBean(IMaintainMalfunctionWorkService.class);
	private final IBuildingExtService buildingExtService = SpringUtil.getBean(IBuildingExtService.class);
	private final AlarmSend alarmSend = SpringUtil.getBean(AlarmSend.class);
	private final IMaintainMalfunctionLogService malfunctionLogService = SpringUtil.getBean(IMaintainMalfunctionLogService.class);
	private final IElevatorService elevatorService = SpringUtil.getBean(IElevatorService.class);
	private final ProjectApiConfiguration projectApiConfiguration = SpringUtil.getBean(ProjectApiConfiguration.class);
	private final IUserService userService = SpringUtil.getBean(IUserService.class);
	private final AsyncHttpUtil asyncHttpUtil = SpringUtil.getBean(AsyncHttpUtil.class);
	private final RobotUtil robotUtil = SpringUtil.getBean(RobotUtil.class);
	private final IMaintainPlanContentExtService maintainPlanContentExtService = SpringUtil.getBean(IMaintainPlanContentExtService.class);
	private final Process process = SpringUtil.getBean(Process.class);

	private static final String NOTE_PUSH_URL = "/tlw/alarm/note/push";
	private static final String OFFICIAL_ACCOUNTS_PUSH_URL = "/tlw/alarm/official/accounts/push";

	@Override
	public IPage<Map<String, Object>> page(Map<String, Object> param, Query query) {
		return businessApproveService.malfunctionPage(param, Condition.getPage(query));
	}

	@Override
	public boolean addApprove(BusinessApproveVO businessApprove) {
		// 手动开启事务
		TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
		try {
			boolean result = businessApproveService.save(businessApprove);
			// 插入报故障记录
			malfunctionLogService.insertWorkLog(businessApprove.getWorkOrderId(), WorkTrackStatusEnum.MALFUNCTION.getTypeName() + "-" + PlanContentFormTypeEnum.REPAIR.getName(), MaintainPlanContentStatusEnum.DISABLE.getId());
			if (result) {
				if (businessApprove.getApproveStatus() == ApproveStatusEnum.PASSED.getId()) {
					// 非维保员
					businessApprove.setGroupLeader(true);
					this.approve(businessApprove);
				} else {
					// 推送通知
					TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
						@Override
						public void afterCommit() {
							process.noticeBusinessProcess(NoticeTaskParam.builder()
								.businessType(BusinessType.REPAIR.getCode())
								.triggerNode(TriggerNodeEnum.CREATE.getCode())
								.bizId(businessApprove.getWorkOrderId())
								.tenantId(AuthUtil.getTenantId())
								.build()
							);
						}
					});


//					ElevatorSimpleInfoVO elevatorInfo = maintainPlanContentService.getElevatorSimpleInfo(businessApprove.getWorkOrderId());
//					// 跳转链接
//					String skipUrl = String.format("pages/approve/repairDetail?myApply=2&businessApproveId=%s&elevatorId=%s&planId=%s", businessApprove.getId(), elevatorInfo.getElevatorId(), businessApprove.getWorkOrderId());
//					Map<String, String> templateDataMap = new HashMap<>(8);
//					templateDataMap.put("first", "电梯故障需要您审核");
//					templateDataMap.put("keyword1", elevatorInfo.getBuildingName());
//					templateDataMap.put("keyword2", elevatorInfo.getElevatorAddress());
//					templateDataMap.put("keyword3", DateUtil.formatDateTime(new Date()));
//					templateDataMap.put("keyword4", MaintainPlanContentEnum.MAINTAIN_WX.getName());
//					templateDataMap.put("remark", "请尽快审核!");
//					templateDataMap.put("params", skipUrl);
//					ApproveUserVO approveUser = userService.getApproveUser(businessApprove.getSubmitId());
//					for (SimpleUserVO groupUser : approveUser.getGroupUsers()) {
//						if (Func.isNotEmpty(groupUser.getOpenid())) {
//							log.info("===========给组长发送模板消息,审批人:[{}]===========", groupUser.getUserName());
//							weChatDialogueService.sendMsg(groupUser.getOpenid(), TemplateMsgConstant.T_DEVICE_FAULT_ID, templateDataMap);
//						}
//
//						log.info("===========给组长发送手机短信,审批人:[{}], 手机号码:[{}]===========", groupUser.getUserName(), groupUser.getPhone());
//						Map<String, String> smsParam = new HashMap<>(2);
//						smsParam.put("auditType", "【待审批】");
//						smsParam.put("auditPosition", "【报障审批】");
//						SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_AUDIT, BladeConstant.ADMIN_TENANT_ID, smsParam, groupUser.getPhone());
//
//						log.info("===========给组长打电话,审批人:[{}], 手机号码:[{}]===========", groupUser.getUserName(), groupUser.getPhone());
//						Map<String, String> phoneMap = new HashMap<>(4);
//						phoneMap.put("place", elevatorInfo.getBuildingName() + elevatorInfo.getElevatorAddress());
//						phoneMap.put("phone", groupUser.getPhone());
////						phoneMap.put("phone", "17322920349");
//						phoneMap.put("templateCode", VoiceConstant.MAINTENANCE_CHECK_USER);
//						asyncHttpUtil.createPost(projectApiConfiguration.getWeb() + "/admin/voice/sendPhone", JSONObject.toJSONString(phoneMap));
//					}
//
//					// 发延迟消息
//					JSONObject jsonObject = new JSONObject();
//					jsonObject.put("businessApproveId", businessApprove.getId());
//					jsonObject.put("approveUsers", approveUser.getManagerUsers());
//					jsonObject.put("templateDataMap", templateDataMap);
//					// 五分钟
//					long date = System.currentTimeMillis() + 60000;
//					alarmSend.sendAlarmDelayed(date, jsonObject.toJSONString());
				}
			}
		} catch (Exception e) {
			platformTransactionManager.rollback(transactionStatus);
			e.printStackTrace();
			throw new ServiceException("报障失败: " + e.getMessage());
		}

		platformTransactionManager.commit(transactionStatus);
		return true;
	}

	@Override
	public boolean approve(BusinessApproveVO businessApproveVO) {
		BusinessApprove businessApprove = businessApproveService.getById(businessApproveVO.getId());
		if (Func.isEmpty(businessApprove)) {
			throw new ServiceException("未找到相关流程!");
		}

		// 手动开启事务
		TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
		try {
			businessApprove.setApproveStatus(businessApproveVO.getApproveStatus());
			businessApprove.setRemark(businessApproveVO.getRemark());
			boolean result = businessApproveService.updateById(businessApprove);
			if (result) {
				SimpleUserVO submitInfo = userService.getSimpleUserInfo(businessApprove.getSubmitId());
				ElevatorSimpleInfoVO elevatorInfo = maintainPlanContentService.getElevatorSimpleInfo(businessApprove.getWorkOrderId());
				MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(businessApprove.getWorkOrderId());

				//计算维修达到时间
				Long buildingId = elevatorService.getById(maintainPlanContent.getElevatorId()).getBuildingId();
				BuildingExt buildingExt = buildingExtService.getOne(Wrappers.<BuildingExt>lambdaQuery().eq(BuildingExt::getBuildingId, buildingId));
				RepairWorkVO repairWorkVO = new RepairWorkVO();
				if (StrUtil.isNotEmpty(buildingExt.getMalfunctionWorkArrivalTime())) {
					//预计达到时间
					long timeMillis = System.currentTimeMillis();
					if (buildingExt.getMalfunctionWorkArrivalTime().contains("m")) {
						Long time = Convert.toLong(buildingExt.getMalfunctionWorkArrivalTime().replace("m", "")) * 60 * 1000;
						timeMillis = timeMillis + time;
						Date date2 = new Date(timeMillis);
						repairWorkVO.setPlanArriveDate(date2);
					} else if (buildingExt.getMalfunctionWorkArrivalTime().contains("h")) {
						Long time = Convert.toLong(buildingExt.getMalfunctionWorkArrivalTime().replace("h", "")) * 60 * 60 * 1000;
						timeMillis = timeMillis + time;
						Date date2 = new Date(timeMillis);
						repairWorkVO.setPlanArriveDate(date2);
					}
				}


				switch (ApproveStatusEnum.getByStatus(businessApproveVO.getApproveStatus())) {
					// 通过
					case PASSED: {
						// 更新工单状态
						if (maintainPlanContent.getStatus() != TaskStatusEnum.WX_PENDING.getStatus()) {
							throw new ServiceException("工单已经开始,不能重复审批!");
						}
						maintainPlanContent.setStatus(TaskStatusEnum.WX_TO_START.getStatus());
						Date date = new Date();
						maintainPlanContent.setPlanDate(date);
						maintainPlanContentService.updateById(maintainPlanContent);

						// 分配维修人
						List<Long> assignUsers = businessApproveVO.getAssignUsers();
						if (Func.isEmpty(assignUsers)) {
							throw new ServiceException("未选择分配人!");
						}

						// 推送通知-报障人
						TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
							@Override
							public void afterCommit() {
								process.noticeBusinessProcess(NoticeTaskParam.builder()
									.businessType(BusinessType.REPAIR.getCode())
									.triggerNode(TriggerNodeEnum.APPROVE_PASS.getCode())
									.bizId(businessApprove.getWorkOrderId())
									.tenantId(AuthUtil.getTenantId())
									.build()
								);
							}
						});

						// 给报障人发送消息
//						if (!businessApproveVO.isGroupLeader() && Func.isNotEmpty(submitInfo) && Func.isNotEmpty(submitInfo.getOpenid())) {
//							log.info("===========给报障人发送模板消息,报障人:[{}], [{}]===========", submitInfo.getUserName(), "已受理");
//							Map<String, String> processedTemplateDataMap = new HashMap<>(8);
//							processedTemplateDataMap.put("first", "您提交的电梯故障 【已受理】");
//							processedTemplateDataMap.put("keyword1", elevatorInfo.getBuildingName());
//							processedTemplateDataMap.put("keyword2", elevatorInfo.getElevatorAddress());
//							processedTemplateDataMap.put("keyword3", DateUtil.formatDateTime(businessApprove.getCreateTime()));
//							processedTemplateDataMap.put("keyword4", "已受理");
//							processedTemplateDataMap.put("keyword5", businessApprove.getRemark());
//							processedTemplateDataMap.put("remark", null);
//							weChatDialogueService.sendMsg(submitInfo.getOpenid(), TemplateMsgConstant.T_REPAIR_PROCESSED_ID, processedTemplateDataMap);
//
//							log.info("===========给报障人发送手机短信,报障人:[{}], 手机号码:[{}]===========", submitInfo.getUserName(), submitInfo.getPhone());
//							Map<String, String> smsParam = new HashMap<>(2);
//							smsParam.put("auditStatus", "【已受理】");
//							SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_STATUS, BladeConstant.ADMIN_TENANT_ID, smsParam, submitInfo.getPhone());
//						}

						MaintainMalfunctionWork maintainMalfunctionWork = maintainMalfunctionWorkService.getOne(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, businessApprove.getWorkOrderId()), false);
						List<String> userName = new ArrayList<>();
						List<String> avatars = new ArrayList<>();
						// 给维修人发送消息
						for (Long assignUser : assignUsers) {
							MaintainPlanContentUser planContentUser = new MaintainPlanContentUser();
							planContentUser.setPlanId(maintainPlanContent.getId());
							planContentUser.setUserId(assignUser);
							if(repairWorkVO.getPlanArriveDate()!=null){
								planContentUser.setPlanArriveDate(new Date(DateUtils.getNowDateEnd(repairWorkVO.getPlanArriveDate())));
							}
							maintainPlanContentUserService.save(planContentUser);
							SimpleUserVO assignUserInfo = userService.getSimpleUserInfo(assignUser);
							if (Func.isNotEmpty(assignUserInfo)) {
								userName.add(assignUserInfo.getUserName());
								avatars.add(assignUserInfo.getAvatar());
//								if (Func.isNotEmpty(assignUserInfo.getOpenid())) {
//									log.info("===========给维修发送模板消息,维修人:[{}]===========", assignUserInfo.getUserName());
//									// 跳转链接
//									String skipUrl = String.format("subpages/repair/repariDetail?elevatorId=%s&planId=%s", elevatorInfo.getElevatorId(), businessApprove.getWorkOrderId());
//									Map<String, String> templateDataMap = new HashMap<>(8);
//									templateDataMap.put("first", "您好，您有新的维修任务!");
//									templateDataMap.put("keyword1", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getName());
//									templateDataMap.put("keyword2", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getPhone());
//									templateDataMap.put("keyword3", DateUtil.format(date, DatePattern.NORM_DATETIME_MINUTE_PATTERN));
//									templateDataMap.put("keyword4", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getMfDesc());
//									templateDataMap.put("remark", "请及时登录梯无忧小程序执行维修任务!");
//									templateDataMap.put("params", skipUrl);
//									weChatDialogueService.sendMsg(assignUserInfo.getOpenid(), TemplateMsgConstant.T_REPAIR_TASK_ID, templateDataMap);
//								}
//
//								log.info("===========给维修人发送手机短信,维修人:[{}], 手机号码:[{}]===========", assignUserInfo.getUserName(), assignUserInfo.getPhone());
//								Map<String, String> smsParam = new HashMap<>(2);
//								smsParam.put("auditStatus", "【待开始】");
//								SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_PEOPLE, BladeConstant.ADMIN_TENANT_ID, smsParam, assignUserInfo.getPhone());
//
//								log.info("===========给维修人打电话,审批人:[{}], 手机号码:[{}]===========", assignUserInfo.getUserName(), assignUserInfo.getPhone());
//								Map<String, String> phoneMap = new HashMap<>(4);
//								phoneMap.put("place", elevatorInfo.getBuildingName() + elevatorInfo.getElevatorAddress());
//								phoneMap.put("phone", assignUserInfo.getPhone());
////								phoneMap.put("phone", "17322920349");
//								phoneMap.put("templateCode", VoiceConstant.MAINTENANCE_ADD_USER);
//								asyncHttpUtil.createPost(projectApiConfiguration.getWeb() + "/admin/voice/sendPhone", JSONObject.toJSONString(phoneMap));
							}
						}

						// 推送通知-维修人
						TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
							@Override
							public void afterCommit() {
								process.noticeBusinessProcess(NoticeTaskParam.builder()
									.businessType(BusinessType.REPAIR.getCode())
									.triggerNode(TriggerNodeEnum.ASSIGN.getCode())
									.bizId(businessApprove.getWorkOrderId())
									.tenantId(AuthUtil.getTenantId())
									.build()
								);
							}
						});

						// 机器人消息内容
						RobotContentDTO robotContentDTO = new RobotContentDTO();
						robotContentDTO.setMaintainType(MaintainPlanContentEnum.MAINTAIN_WX.getId());
						robotContentDTO.setMaintainSubTypeDesc("【维修派单通知】");
						StringBuilder locationDesc = new StringBuilder();
						locationDesc.append(elevatorInfo.getBuildingName()).append("-").append(elevatorInfo.getElevatorAddress());
						robotContentDTO.setLocationDesc(locationDesc.toString());
						robotContentDTO.setMaintainStatusDesc(TaskStatusEnum.WX_UNDER_WAY.getName());
						robotContentDTO.setElevatorStatusDesc(ElevatorStatusEnum.getName(elevatorInfo.getIsStop()));
						robotContentDTO.setMaintainPersonDesc(String.join(",", userName));
						robotContentDTO.setMaintainPersonImgDesc(String.join(",", avatars));
						String maintainTimeDesc = DateUtils.chineseDate(maintainPlanContent.getPlanDate());
						robotContentDTO.setMaintainTimeDesc(maintainTimeDesc.substring(0, maintainTimeDesc.length() - 6));
						// 2024-05-59 修复malfunctionWork 为空 导致的 无法报障问题
						if (!Func.isNull(maintainMalfunctionWork)) {
							robotContentDTO.setMalfunctionDesc(maintainMalfunctionWork.getMfDesc());
						}
						robotUtil.sendRobotMessage(RequestContextHolder.getRequestAttributes(), maintainPlanContent.getElevatorId(), maintainPlanContent.getId(), robotContentDTO);

						// 给飞书推送表格更新
						if ("592800".equals(AuthUtil.getTenantId())) {
							asyncHttpUtil.createPost(projectApiConfiguration.getWeb() + "/admin/lark/galaxy/elevator/repair/plan", Func.toJson(maintainPlanContent), WebUtil.getRequest());
						}

						// 更新分配时间与分配次数
						MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, maintainPlanContent.getId()), false);
						Date now = new Date();
						maintainPlanContentExt.setAllocateTime(now);
						long allocateDuration = now.getTime() - maintainPlanContent.getCreateTime().getTime();
						maintainPlanContentExt.setAllocateDuration(allocateDuration < 0 ? 0 : allocateDuration);
						maintainPlanContentExt.setAssignmentCounts(maintainPlanContentExt.getAssignmentCounts() + 1);
						maintainPlanContentExtService.updateById(maintainPlanContentExt);

						// 插入任务跟踪信息
						malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), WorkTrackStatusEnum.PASS.getTypeName(), TaskStatusEnum.WX_TO_START.getStatus());
						malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), WorkTrackStatusEnum.ADD_USER.getTypeName() + "[" + StrUtil.join("/", userName) + "]", TaskStatusEnum.WX_TO_START.getStatus());


						//新增预警信息
						repairWorkVO.setUserIds(assignUsers);
						maintainMalfunctionWorkService.sendYjMsg(repairWorkVO, maintainPlanContent.getId());

						break;
					}
					// 驳回
					case REJECT: {
						// 更新工单状态
						if (maintainPlanContent.getStatus() != TaskStatusEnum.WX_TO_START.getStatus() && maintainPlanContent.getStatus() != TaskStatusEnum.WX_PENDING.getStatus()) {
							throw new ServiceException("工单已经开始,不能关闭或者撤回");
						}
						maintainPlanContent.setStatus(TaskStatusEnum.WX_TURN_DOWN.getStatus());
						maintainPlanContentService.updateById(maintainPlanContent);
						// 更新电梯停梯状态
						elevatorService.updateElevatorIsStop(maintainPlanContent.getElevatorId(), ElevatorStatusEnum.NORMAL.getStatus());

						// 插入任务跟踪信息
						malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), WorkTrackStatusEnum.REJECT.getTypeName(), maintainPlanContent.getStatus());

						// 推送通知
						TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
							@Override
							public void afterCommit() {
								process.noticeBusinessProcess(NoticeTaskParam.builder()
									.businessType(BusinessType.REPAIR.getCode())
									.triggerNode(TriggerNodeEnum.APPROVE_NOT_PASS.getCode())
									.bizId(businessApprove.getWorkOrderId())
									.tenantId(AuthUtil.getTenantId())
									.build()
								);
							}
						});

//						if (Func.isNotEmpty(submitInfo)) {
//							if (Func.isNotEmpty(submitInfo.getOpenid())) {
//								log.info("===========给报障人发送模板消息,报障人:[{}], [{}]===========", submitInfo.getUserName(), "未受理");
//								Map<String, String> processedTemplateDataMap = new HashMap<>(8);
//								processedTemplateDataMap.put("first", "您提交的电梯故障 【未受理】");
//								processedTemplateDataMap.put("keyword1", elevatorInfo.getBuildingName());
//								processedTemplateDataMap.put("keyword2", elevatorInfo.getElevatorAddress());
//								processedTemplateDataMap.put("keyword3", DateUtil.formatDateTime(businessApprove.getCreateTime()));
//								processedTemplateDataMap.put("keyword4", "未受理");
//								processedTemplateDataMap.put("keyword5", businessApprove.getRemark());
//								processedTemplateDataMap.put("remark", null);
//								weChatDialogueService.sendMsg(submitInfo.getOpenid(), TemplateMsgConstant.T_REPAIR_PROCESSED_ID, processedTemplateDataMap);
//							}
//
//							log.info("===========给报障人发送手机短信,报障人:[{}], 手机号码:[{}]===========", submitInfo.getUserName(), submitInfo.getPhone());
//							Map<String, String> smsParam = new HashMap<>(2);
//							smsParam.put("auditStatus", "【未受理】");
//							SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_STATUS, BladeConstant.ADMIN_TENANT_ID, smsParam, submitInfo.getPhone());
//						}
						break;
					}
					default:
						break;
				}
			}
		} catch (Exception e) {
			platformTransactionManager.rollback(transactionStatus);
			e.printStackTrace();
			throw new ServiceException("报障审批失败: " + e.getMessage());
		}

		platformTransactionManager.commit(transactionStatus);
		return true;
	}

	/**
	 * 每天只可以催办2次
	 *
	 * @param businessApproveId
	 * @return
	 */
	@Override
	public boolean reminder(Long businessApproveId) {
		BusinessApprove businessApprove = businessApproveService.getById(businessApproveId);
		if (Func.isEmpty(businessApprove)) {
			throw new ServiceException("未找到相关流程!");
		}
		if (businessApprove.getApproveStatus() != ApproveStatusEnum.PENDING.getId()) {
			throw new ServiceException("该报障已审批，无需催办!");
		}

		String reminderKey = TemplateMsgConstant.REMINDER_KEY.concat(StringPool.DASH).concat(String.valueOf(businessApproveId));
		long count;
		if (bladeRedis.exists(reminderKey)) {
			count = bladeRedis.incr(reminderKey);
		} else {
			count = bladeRedis.incr(reminderKey);
			bladeRedis.expire(reminderKey, Duration.ofDays(1));
		}

		if (count > 2) {
			throw new ServiceException("您今天的催办次数已经超过上限!");
		}

		// 推送通知
		process.noticeBusinessProcess(NoticeTaskParam.builder()
			.businessType(BusinessType.REPAIR.getCode())
			.triggerNode(TriggerNodeEnum.REMINDER.getCode())
			.bizId(businessApprove.getWorkOrderId())
			.tenantId(AuthUtil.getTenantId())
			.build());

//		ElevatorSimpleInfoVO elevatorInfo = maintainPlanContentService.getElevatorSimpleInfo(businessApprove.getWorkOrderId());
//		Map<String, String> templateDataMap = new HashMap<>(8);
//		templateDataMap.put("first", "电梯故障需要您审核");
//		templateDataMap.put("keyword1", elevatorInfo.getBuildingName());
//		templateDataMap.put("keyword2", elevatorInfo.getElevatorAddress());
//		templateDataMap.put("keyword3", DateUtil.formatDateTime(new Date()));
//		templateDataMap.put("keyword4", MaintainPlanContentEnum.MAINTAIN_WX.getName());
//		templateDataMap.put("remark", "请尽快审核!");
//
//		List<Long> approveIds = Func.toLongList(businessApprove.getApproveIds());
//		for (Long approveId : approveIds) {
//			SimpleUserVO approveInfo = userService.getSimpleUserInfo(approveId);
//			if (Func.isNotEmpty(approveInfo)) {
//				if (Func.isNotEmpty(approveInfo.getOpenid())) {
//					log.info("发送催办模板消息,审批人:[{}]", approveInfo.getUserName());
//					weChatDialogueService.sendMsg(approveInfo.getOpenid(), TemplateMsgConstant.T_DEVICE_FAULT_ID, templateDataMap);
//				}
//
//				log.info("===========发送催办手机短信,审批人:[{}], 手机号码:[{}]===========", approveInfo.getUserName(), approveInfo.getPhone());
//				Map<String, String> smsParam = new HashMap<>(2);
//				smsParam.put("auditType", "【待审批】");
//				smsParam.put("auditPosition", "【报障审批】");
//				SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_AUDIT, BladeConstant.ADMIN_TENANT_ID, smsParam, approveInfo.getPhone());
//
//				log.info("===========打催办电话,审批人:[{}], 手机号码:[{}]===========", approveInfo.getUserName(), approveInfo.getPhone());
//				Map<String, String> phoneMap = new HashMap<>(4);
//				phoneMap.put("place", elevatorInfo.getBuildingName() + elevatorInfo.getElevatorAddress());
//				phoneMap.put("phone", approveInfo.getPhone());
////				phoneMap.put("phone", "17322920349");
//				phoneMap.put("templateCode", VoiceConstant.MAINTENANCE_CHECK_USER);
//				asyncHttpUtil.createPost(projectApiConfiguration.getWeb() + "/admin/voice/sendPhone", JSONObject.toJSONString(phoneMap));
//			}
//		}

		return true;
	}

	@Override
	public boolean cancel(Long businessApproveId) {
		BusinessApprove businessApprove = businessApproveService.getById(businessApproveId);
		if (Func.isEmpty(businessApprove)) {
			throw new ServiceException("未找到相关流程!");
		}
		if (businessApprove.getApproveStatus() != ApproveStatusEnum.PENDING.getId()) {
			throw new ServiceException("工单已开始，不能撤回!");
		}

		// 手动开启事务
		TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
		try {
			MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(businessApprove.getWorkOrderId());
			if (Func.isEmpty(maintainPlanContent)) {
				throw new ServiceException("未找到对应工单!");
			}
			businessApprove.setApproveStatus(ApproveStatusEnum.CANCEL.getId());
			if (businessApproveService.updateById(businessApprove)) {
				maintainPlanContent.setStatus(TaskStatusEnum.WX_CLOSED.getStatus());
				maintainPlanContentService.updateById(maintainPlanContent);
				// 更新电梯停梯状态
//				elevatorService.updateElevatorIsStop(maintainPlanContent.getElevatorId(), ElevatorStatusEnum.NORMAL.getStatus());
				// 插入任务跟踪信息
				malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), WorkTrackStatusEnum.CANCEL.getTypeName(), maintainPlanContent.getStatus());
			}
		} catch (Exception e) {
			platformTransactionManager.rollback(transactionStatus);
			e.printStackTrace();
			throw new ServiceException("报障撤回失败: " + e.getMessage());
		}

		platformTransactionManager.commit(transactionStatus);
		return true;
	}

	@Override
	public boolean close(Long businessApproveId) {
		BusinessApprove businessApprove = businessApproveService.getById(businessApproveId);
		MaintainPlanContent planContent = maintainPlanContentService.getById(businessApprove.getWorkOrderId());
//		ElevatorSimpleInfoVO elevatorInfo = maintainPlanContentService.getElevatorSimpleInfo(businessApprove.getWorkOrderId());
//		MaintainMalfunctionWork malfunctionWork = maintainMalfunctionWorkService.getOne(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, businessApprove.getWorkOrderId()));
		TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition);
		try {
			if (planContent.getStatus().equals(TaskStatusEnum.WX_TO_START.getStatus())) {
				planContent.setStatus(TaskStatusEnum.WX_CHECK_PASS_CLOSED.getStatus());
				maintainPlanContentService.updateById(planContent);
				// 插入任务跟踪信息
				malfunctionLogService.insertWorkLog(planContent.getId(), WorkTrackStatusEnum.MAL_CLOSE.getTypeName(), planContent.getStatus());

				if (PlanContentFormTypeEnum.BUILDING.getId().equals(planContent.getPlanFrom())) {
					// 推送通知
					TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
						@Override
						public void afterCommit() {
							process.noticeBusinessProcess(NoticeTaskParam.builder()
								.businessType(BusinessType.REPAIR.getCode())
								.triggerNode(TriggerNodeEnum.CLOSE.getCode())
								.bizId(businessApprove.getWorkOrderId())
								.tenantId(AuthUtil.getTenantId())
								.build()
							);
						}
					});

//					SimpleUserVO userVO = userService.getSimpleEstateUserByPhone(malfunctionWork.getPhone());
//					// 发送物业端公众号消息
//					if (ObjectUtil.isNotEmpty(userVO) && StringUtil.isNotBlank(userVO.getOpenid())) {
//						log.info("===========给报障人发送模板消息,报障人:[{}], [{}]===========", userVO.getUserName(), "已关闭");
//						Map<String, Object> wxMap = new HashMap<>(3);
//						Map<String, String> processedTemplateDataMap = new HashMap<>(8);
//						processedTemplateDataMap.put("first", "您提交的电梯故障 【已关闭】");
//						processedTemplateDataMap.put("keyword1", elevatorInfo.getBuildingName());
//						processedTemplateDataMap.put("keyword2", elevatorInfo.getElevatorAddress());
//						processedTemplateDataMap.put("keyword3", DateUtil.formatDateTime(businessApprove.getCreateTime()));
//						processedTemplateDataMap.put("keyword4", "已关闭");
//						processedTemplateDataMap.put("keyword5", businessApprove.getRemark());
//						processedTemplateDataMap.put("remark", "");
//						wxMap.put("openid", userVO.getOpenid());
//						wxMap.put("params", processedTemplateDataMap);
//						wxMap.put("templateId", TemplateMsgConstant.T_REPAIR_PROCESSED_ID);
//						HttpUtil.createPost(projectApiConfiguration.getEstate() + OFFICIAL_ACCOUNTS_PUSH_URL).body(JSONObject.toJSONString(wxMap)).execute().body();
//					}
//					// 发送短信
//					log.info("===========给报障人发送手机短信,报障人:[{}], 手机号码:[{}]===========", malfunctionWork.getName(), malfunctionWork.getPhone());
//					HashMap<String, Object> map = new HashMap<>(3);
//					Map<String, String> smsParam = new HashMap<>(2);
//					smsParam.put("auditStatus", "【已关闭】");
//					map.put("phone", malfunctionWork.getPhone());
//					map.put("params", smsParam);
//					map.put("smsCode", MaintenanceSmsConstant.MAINTENANCE_STATUS);
//					HttpUtil.createPost(projectApiConfiguration.getEstate() + NOTE_PUSH_URL).body(JSONObject.toJSONString(map)).execute().body();
				}
			}
		} catch (Exception e) {
			platformTransactionManager.rollback(transactionStatus);
			e.printStackTrace();
			throw new ServiceException("报障关闭失败: " + e.getMessage());
		}

		platformTransactionManager.commit(transactionStatus);
		return Boolean.TRUE;
	}
}
